#!/usr/bin/env python
import gtk,gobject
import sysaccess
from location import Location
from share import *
from location_window import LocationWindow
from share_window import ShareWindow
from window_template import WindowTemplate
from pygtk_thread import PygtkThread

class MainWindow(WindowTemplate):
    def __init__(self):
        self.create_window()
        self.id , self.locations = sysaccess.load()
        self.refresh_treeview()
        self.current_location = sysaccess.get_current_location(self.locations)
        gobject.timeout_add(10000,self.update_shares)
        self.main()
    
    def create_window(self):
        self.window = gtk.Window(type=gtk.WINDOW_TOPLEVEL)
        self.window.set_title("Miam")
        self.window.set_size_request(450,650)
        self.window.connect("destroy", self.destroy)
        self.window.connect("delete_event", self.delete_event)
        
        self.create_uimanager()
        self.create_treeview()
        self.create_expander()
        
        #Global VBox
        global_vbox = gtk.VBox()
        
        #Menu
        global_vbox.pack_start(self.menubar,False,False)
        #Toolbar
        global_vbox.pack_start(self.toolbar,False,False)
        #Trayicon
        self.trayicon = gtk.StatusIcon()
        self.trayicon.set_from_stock(gtk.STOCK_HOME)
        self.trayicon.connect("activate",self.trayicon_activate_callback)
        self.trayicon.connect("popup-menu",self.trayicon_popup_menu_callback)
        self.trayicon.set_visible(True)
        
        #Treeview
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_NEVER,gtk.POLICY_AUTOMATIC)
        scrolled_window.add(self.treeview)
        global_vbox.pack_start(scrolled_window)
        
        #Expander
        global_vbox.pack_start(self.expander)
        
        self.window.add(global_vbox)
        self.window.show_all()
    
    def create_uimanager(self):
        self.uimanager = gtk.UIManager()
        uimanager_accel_group = self.uimanager.get_accel_group()
        self.window.add_accel_group(uimanager_accel_group)
        #Menubar
        menubar_action_group = gtk.ActionGroup('menubar_action_group')
        menubar_action_group.add_actions([('file',None,'_File'),
                                            ('import',gtk.STOCK_GOTO_FIRST,'_Import',None,'Import a miam file',self.import_callback),
                                            ('export',gtk.STOCK_GOTO_LAST,'_Export',None,'Export a miam file',self.export_callback),
                                            ('exit',gtk.STOCK_QUIT,'_Exit',None,'Exit Miam',self.exit),
                                          ('edit',None,'_Edit'),
                                            ('add location',gtk.STOCK_ADD,'_Add Location',None,'Add a location',self.add_location_callback),
                                          ('tools',None,'_Tools')
                                          ])
        self.uimanager.insert_action_group(menubar_action_group,0)
        #Toolbar
        toolbar_action_group = gtk.ActionGroup('toolbar_action_group')
        toolbar_action_group.add_actions([('add location',gtk.STOCK_ADD,'_Add Location',None,'Add a location',self.add_location_callback), #sert a rien pke c l'autre qui est utilise (ajoute en 1er)
                                          ('add share',gtk.STOCK_ADD,'_Add Share',None,'Add a share',self.add_share_callback),
                                          ('edit item',gtk.STOCK_EDIT,'_Edit Item',None,'Edit Item',self.edit_item_callback),
                                          ('remove item',gtk.STOCK_DELETE,'_Remove Item',None,'Remove Item',self.remove_item_callback)
                                          ])
        self.uimanager.insert_action_group(toolbar_action_group,0)
        #Trayicon menu
        tray_action_group = gtk.ActionGroup('tray_action_group')
        tray_action_group.add_actions = ([('exit',gtk.STOCK_QUIT,'_Exit',None,'Exit Miam',self.exit)])
        self.uimanager.insert_action_group(tray_action_group,0)
        
        self.uimanager.add_ui_from_file('ui.xml')
        self.menubar = self.uimanager.get_widget('/menubar')
        self.toolbar = self.uimanager.get_widget('/toolbar')
        self.traymenu = self.uimanager.get_widget('/traymenu')
    
    def create_treeview(self):
        self.treemodel = gtk.TreeStore( gobject.TYPE_INT,
                                        gobject.TYPE_STRING,
                                        gobject.TYPE_STRING,
                                        gobject.TYPE_STRING,
                                        gobject.TYPE_BOOLEAN )
        
        self.treemodelsort = gtk.TreeModelSort(self.treemodel)
        self.treemodelsort.set_sort_column_id(1,gtk.SORT_ASCENDING)
        
        cr_name = gtk.CellRendererText()
        cr_type = gtk.CellRendererText()
        cr_latency = gtk.CellRendererText() 
        cr_automount = gtk.CellRendererToggle()
        cr_automount.connect('toggled', self.cb_automount_callback)
        
        col_name = gtk.TreeViewColumn("Name", cr_name,text=1)
        col_type = gtk.TreeViewColumn("Type", cr_type,text=2)
        col_latency = gtk.TreeViewColumn("Latency",cr_latency,text=3)
        col_automount = gtk.TreeViewColumn("Auto", cr_automount)
        col_automount.add_attribute(cr_automount, "active",4)
        self.treeview = gtk.TreeView(self.treemodelsort)
        self.treeview.connect("cursor-changed",self.row_changed_callback)
        self.treeview.append_column( col_name )
        self.treeview.append_column( col_type )
        self.treeview.append_column( col_latency )
        self.treeview.append_column( col_automount )
    
    def create_expander(self):
        self.expander = gtk.Expander(label="Info")
        #global info
                
        #location vbox
        lbl_location_name = gtk.Label("Name :")
        self.lbl_location_name = gtk.Label("")
        location_hbox_name = self.build_hbox((lbl_location_name,self.lbl_location_name))
        
        self.param_expander = gtk.Expander(label="Parametre")
        
        self.location_vbox = self.build_vbox((location_hbox_name,self.param_expander))
        self.location_vbox.show_all()
        
        #share vbox
        lbl_share_name = gtk.Label("Name :")
        self.lbl_share_name = gtk.Label("")
        share_hbox_name = self.build_hbox((lbl_share_name,self.lbl_share_name))
        
        lbl_share_location = gtk.Label("Location :")
        self.lbl_share_location =gtk.Label("")
        share_hbox_location = self.build_hbox((lbl_share_location,self.lbl_share_location))
        
        lbl_share_server = gtk.Label("Server :")
        self.lbl_share_server =gtk.Label("")
        share_hbox_server = self.build_hbox((lbl_share_server,self.lbl_share_server))
        
        lbl_share_mountpoint = gtk.Label("Mount Point :")
        self.lbl_share_mountpoint =gtk.Label("")
        share_hbox_mountpoint = self.build_hbox((lbl_share_mountpoint,self.lbl_share_mountpoint))
        
        lbl_share_mounted = gtk.Label("Mounted :")
        self.lbl_share_mounted =gtk.Label("")
        share_hbox_mounted = self.build_hbox((lbl_share_mounted,self.lbl_share_mounted))
        
        lbl_share_protocol = gtk.Label("Protocol :")
        self.lbl_share_protocol =gtk.Label("")
        share_hbox_protocol = self.build_hbox((lbl_share_protocol,self.lbl_share_protocol))
        
        lbl_share_path = gtk.Label("Path :")
        self.lbl_share_path = gtk.Label("")
        self.share_hbox_path = self.build_hbox((lbl_share_path,self.lbl_share_path))
        
        lbl_share_domain = gtk.Label("Domain :")
        self.lbl_share_domain = gtk.Label("")
        self.share_hbox_domain = self.build_hbox((lbl_share_domain,self.lbl_share_domain))
        
        
        self.share_vbox = self.build_vbox((share_hbox_name,share_hbox_location,share_hbox_server,share_hbox_mountpoint,share_hbox_mounted,share_hbox_protocol,self.share_hbox_path,self.share_hbox_domain))
        self.share_vbox.show_all()
        
    def get_new_id(self):
        self.id += 1
        return self.id
    
    def get_item(self,path=None):
        if path == None:
            path = self.treeview.get_cursor()[0]
        if path:
            if len(path) == 1 :
                return self.locations[self.treemodelsort[path][0]]
            elif len(path) == 2 :
                return self.locations[self.treemodelsort[path[0]][0]].shares[self.treemodelsort[path][0]]
                            
    def add(self,item):
        if item.__class__.__name__ == "Location":
            self.locations[item.id] = item
        elif item.__class__.__name__ == "Share" :
            self.locations[item.location.id].shares[item.id] = item
        self.refresh_treeview()    
    
    def remove(self,item):
        if item.__class__.__name__ == "Location":
            del self.locations[item.id]
        elif item.__class__.__name__ == "Share" :
            del self.locations[item.location.id].shares[item.id]
        self.refresh_treeview()
    
    def edit(self,item):
        if item.__class__.__name__ == "Location":
            location_window = LocationWindow(item)
            location_window.main()
        elif item.__class__.__name__ == "Share":
            share_window = ShareWindow(self.locations,item)
            share_window.main()
        self.refresh_treeview()
        
    def refresh_treeview(self):
        self.treemodel.clear()
        for location in self.locations:
            item = self.locations[location]
            location_iter = self.treemodel.append(None,(item.id,item.name,"","",item.automount))
            for share in self.locations[location].shares:
                item = self.locations[location].shares[share]
                self.treemodel.append(location_iter,(item.id,item.name,item.protocol,item.latency,item.automount))
        self.treeview.expand_all()
        
    def fill_expander(self):
        item=self.get_item()
        if self.expander.get_child():
            self.expander.remove(self.expander.get_child()) 
        
        if item.__class__.__name__ == "Location":
            self.lbl_location_name.set_text(item.name)
            self.expander.add(self.location_vbox)
            param_vbox = gtk.VBox()
            if self.param_expander.get_child():
                self.param_expander.remove(self.param_expander.get_child())
            self.param_expander.add(param_vbox)
            for param in item.param_location:
                for value in item.param_location[param]:
                    param_vbox.pack_start(self.build_hbox((gtk.Label(param+" :"),gtk.Label(value))))
            param_vbox.show_all()
            
        elif item.__class__.__name__ == "Share":
            self.lbl_share_name.set_text(item.name)
            location_item = item.location
            self.lbl_share_location.set_text(location_item.name)
            self.lbl_share_server.set_text(item.server)
            self.lbl_share_mountpoint.set_text(item.mount_point)
            if item.mounted:
                self.lbl_share_mounted.set_text("Yes")
            else:
                self.lbl_share_mounted.set_text("No")
            self.lbl_share_protocol.set_text(item.protocol)
            if item.path != "":           
                self.lbl_share_path.set_text(item.path)
                self.share_hbox_path.show_all()
            else:
                self.share_hbox_path.hide_all()
            
            if item.domain != "":           
                self.lbl_share_domain.set_text(item.domain)
                self.share_hbox_domain.show_all()
            else:
                self.share_hbox_domain.hide_all()    
                
            self.expander.add(self.share_vbox)
            
    
    ##Callbacks
    def update_shares(self):
        for location_id in self.locations:
            for share_id in self.locations[location_id].shares:
                PygtkThread(self.update_share_thread_action,self.refresh_treeview).start(self.locations[location_id].shares[share_id])
        return True #for gobject to call that method again
            
    def update_share_thread_action(self,share):
        share.latency = sysaccess.get_host_latency(share.server,share.port)
        if share.latency.__class__.__name__ != 'int':
            share.latency = "unreachable"
   
    def row_changed_callback(self,widget):
        self.expander.set_expanded(True)
        self.fill_expander()
    
    def import_callback(self,widget=None):
        loc1 = Location(self.get_new_id())
        loc1.name = "loc1"
        share1 = Share(self.get_new_id())
        share1.name = "share1"
        share1.location = loc1
        share1.protocol = "samba"
        share1.server = 'bodji.net'
        share2 = Share(self.get_new_id())
        share2.name = "share2"
        share2.location = loc1
        share2.protocol = "ssh"
        share2.server = 'baloo.dyndns.org'
        loc1.shares = {share1.id : share1 , share2.id : share2}
        loc2 = Location(self.get_new_id())
        loc2.name = "loc2"
        share3 = Share(self.get_new_id())
        share3.name = "share3"
        share3.location = loc2
        share3.protocol = "ftp"
        share4 = Share(self.get_new_id())
        share4.name = "share4"
        share4.location = loc2
        share4.protocol = "nfs"
        loc2.shares = {share3.id : share3 , share4.id : share4}
        self.add(loc1)
        self.add(loc2)
        print "import"
    
    def export_callback(self,widget=None):
        self.update_shares()

    def add_location_callback(self,widget=None):
        location_window = LocationWindow()
        new_location = location_window.main()
        if new_location:
            new_location.id = self.get_new_id()
            self.add(new_location)
        
    def add_share_callback(self,widget=None):
        share_window = ShareWindow(self.locations)
        new_share = share_window.main()
        if new_share:
            new_share.id = self.get_new_id()
            self.add(new_share)
    
    def edit_item_callback(self,widget=None):
        item = self.get_item()
        if item:
            self.edit(item)
    
    def remove_item_callback(self,widget=None):
        item = self.get_item()
        if item:
            self.remove(item)
    
    def trayicon_activate_callback(self,widget=None):
        print "activate trayicon"
    
    def trayicon_popup_menu_callback(self,widget,button,time):
        if button == 3 :
            self.traymenu.popup(None, None, None, button, time)
    
    def cb_automount_callback(self,widget,sorted_path):
        if len(sorted_path) > 1 :
            sorted_path = tuple([int(i) for i in sorted_path.split(':')])
        elif len(sorted_path) == 1 :
            sorted_path = (int(sorted_path),)
        path = self.treemodelsort.convert_path_to_child_path(sorted_path)
        self.treemodel[path][4] = not self.treemodel[path][4]
        self.get_item(sorted_path).automount = self.treemodelsort[sorted_path][4]
                
    def exit(self,widget=None):
        self.destroy()
    
    def delete_event(self, widget, event):
        return False
      
    def destroy(self, widget=None):
        sysaccess.save(self.id,self.locations)
        gtk.main_quit()
        
    def main(self):
        gtk.main()
        
if __name__ == '__main__':
    main_window = MainWindow()